package com.redepronik.negosys.invfac.service;

import static com.redepronik.negosys.utils.Utils.parametro;
import static com.redepronik.negosys.utils.Utils.presentaMensaje;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.faces.application.FacesMessage;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.redepronik.negosys.invfac.dao.GuiaRemisionDao;
import com.redepronik.negosys.invfac.entity.Detalleegreso;
import com.redepronik.negosys.invfac.entity.Detalleguiaremision;
import com.redepronik.negosys.invfac.entity.Egreso;
import com.redepronik.negosys.invfac.entity.Guiaremision;
import com.redepronik.negosys.rrhh.entity.Empleadocargo;
import com.redepronik.negosys.rrhh.entity.Persona;
import com.redepronik.negosys.rrhh.service.EmpleadoService;

@Service
public class GuiaRemisionServiceImpl implements GuiaRemisionService {

	@Autowired
	private GuiaRemisionDao guiaRemisionDao;

	@Autowired
	private EgresoService egresoService;

	@Autowired
	private ParametroService parametroService;

	@Autowired
	private EmpleadoService empleadoService;

	@Autowired
	private LocalService localService;

	@Autowired
	private MotivoTrasladoService motivoTrasladoService;

	public Long contar() {
		return guiaRemisionDao
				.contar("select count(*) from Guiaremision gr where and gr.activo=true",
						new Object[] {}).longValue();
	}

	public void insertar(Guiaremision guiaRemision, Persona cliente,
			Empleadocargo transportista,
			List<Detalleguiaremision> listDetalleGuiaRemision,
			List<Egreso> listaFacturasGuiaRemision) {
		if (!comprobarGuiaRemision(guiaRemision, transportista,
				listDetalleGuiaRemision)) {
			if (cliente.getPersonaid() == null) {
				cliente = listaFacturasGuiaRemision.get(0).getCliente()
						.getPersona();
				guiaRemision.setRazonsocialdestinatario("");
			} else {
				guiaRemision.setCliente(cliente.getCliente());
				guiaRemision.setRazonsocialdestinatario(cliente.getCliente()
						.getNombrecomercial());
			}

			guiaRemision.setTransportistaid(empleadoService
					.obtenerPorEmpleadoCargoId(transportista
							.getEmpleadocargoid()));
			guiaRemision.setPuntollegada(cliente.getCiudad().getNombre());
			String ciudad = localService.obtenerPorLocalId(
					listaFacturasGuiaRemision.get(0).getLocal().getLocalid())
					.getCiudad();
			guiaRemision.setPuntopartida(ciudad);

			guiaRemision
					.setDetalleguiaremisions(new ArrayList<Detalleguiaremision>());
			for (Detalleguiaremision dgr : listDetalleGuiaRemision)
				guiaRemision.addDetalleguiaremision(dgr);

			guiaRemision.setEgresos(new ArrayList<Egreso>());
			for (Egreso e : listaFacturasGuiaRemision)
				guiaRemision.addEgreso(e);

			guiaRemision.setMotivotraslado(motivoTrasladoService
					.obtenerPorMotivoTrasladoId(guiaRemision
							.getMotivotraslado().getMotivotrasladoid()));

			guiaRemision.setFechainicio(new Date());
			guiaRemision.setFechaterminacion(new Date());

			int secuencia = 0;
			secuencia = parametro.getSecuenciaremision() + 1;
			parametro.setSecuenciaremision(secuencia);
			parametroService.actualizar(parametro);

			guiaRemision.setCodigodocumento(parametro
					.getCodigoestablecimiento()
					.concat("-")
					.concat(parametro.getCodigoemision().concat("-")
							.concat(String.format("%09d", secuencia))));

			guiaRemisionDao.insertar(guiaRemision);

			presentaMensaje(
					FacesMessage.SEVERITY_INFO,
					"INSERTÓ GUIA REMISION: "
							+ guiaRemision.getCodigodocumento());
		}
	}

	public void insertar(Guiaremision guiaRemision, Egreso egreso,
			Persona cliente, Empleadocargo transportista) {
		if (guiaRemision.getMotivotraslado().getMotivotrasladoid() != 0
				&& transportista.getEmpleadocargoid() != 0
				&& guiaRemision.getPlaca() != null) {
			guiaRemision.setCliente(cliente.getCliente());
			guiaRemision.setRazonsocialdestinatario(cliente.getCliente()
					.getNombrecomercial());
			guiaRemision.setTransportistaid(empleadoService
					.obtenerPorEmpleadoCargoId(transportista
							.getEmpleadocargoid()));
			guiaRemision.setFechainicio(new Date());
			guiaRemision.setFechaterminacion(new Date());
			guiaRemision.setPuntollegada(cliente.getCiudad().getNombre());
			String ciudad = localService.obtenerPorLocalId(
					egreso.getLocal().getLocalid()).getCiudad();
			guiaRemision.setPuntopartida(ciudad);

			guiaRemision.setEgresos(new ArrayList<Egreso>());
			guiaRemision.addEgreso(egreso);

			guiaRemision.setMotivotraslado(motivoTrasladoService
					.obtenerPorMotivoTrasladoId(guiaRemision
							.getMotivotraslado().getMotivotrasladoid()));

			int secuencia = 0;
			secuencia = parametro.getSecuenciaremision() + 1;
			parametro.setSecuenciaremision(secuencia);
			parametroService.actualizar(parametro);

			guiaRemision.setCodigodocumento(parametro
					.getCodigoestablecimiento()
					.concat("-")
					.concat(parametro.getCodigoemision().concat("-")
							.concat(String.format("%09d", secuencia))));

			guiaRemisionDao.insertar(guiaRemision);
		}
	}

	public void cargarCliente(List<Egreso> listaFacturasGuiaRemision,
			Persona cliente) {
		cliente = listaFacturasGuiaRemision.size() == 1 ? listaFacturasGuiaRemision
				.get(0).getCliente().getPersona()
				: new Persona();
	}

	public void cargarDetalleGuiaRemision(Persona cliente,
			List<Egreso> listaFacturasGuiaRemision,
			List<Egreso> listaAuxFactura,
			List<Detalleguiaremision> listDetalleGuiaRemision) {
		if (listaFacturasGuiaRemision.isEmpty())
			presentaMensaje(FacesMessage.SEVERITY_ERROR,
					"DEBE ESCOJER UNA FACTURA", "errorListaFactura", true);
		else {
			List<Detalleegreso> listDetalleEgreso = new ArrayList<Detalleegreso>();
			if (listaAuxFactura.size() != listaFacturasGuiaRemision.size())
				listaAuxFactura.addAll(listaFacturasGuiaRemision);
			listaFacturasGuiaRemision.clear();
			listaFacturasGuiaRemision.addAll(listaAuxFactura);
			cargarCliente(listaFacturasGuiaRemision, cliente);
			for (Egreso egreso : listaFacturasGuiaRemision)
				listDetalleEgreso.addAll(egresoService
						.duplicarDetalleEgreso(egreso.getDetalleegresos()));
			for (Detalleegreso detalleegreso : listDetalleEgreso)
				detalleegreso.setEliminar(true);

			List<Detalleegreso> listDetalleEgresoFinal = egresoService
					.sumarCantidades(listDetalleEgreso);
			for (Detalleegreso de : listDetalleEgresoFinal) {
				Detalleguiaremision dgr = new Detalleguiaremision();
				dgr.setDescripcion(de.getProducto().getEan() + " - "
						+ de.getProducto().getNombreimprimir());
				dgr.setCantidad(de.getCantidad());
				listDetalleGuiaRemision.add(dgr);
			}
			presentaMensaje(FacesMessage.SEVERITY_INFO, "CORRECTO",
					"errorListaFactura", false);
		}
	}

	public boolean comprobarGuiaRemision(Guiaremision guiaRemision,
			Empleadocargo transportista,
			List<Detalleguiaremision> listDetalleGuiaRemision) {
		if (transportista.getEmpleadocargoid() == 0) {
			presentaMensaje(FacesMessage.SEVERITY_ERROR,
					"INGRESE UN TRANSPORTISTA", "error", true);
			return true;
		} else if (guiaRemision.getPlaca().compareTo("") == 0) {
			presentaMensaje(FacesMessage.SEVERITY_ERROR, "INGRESE UNA PLACA",
					"error", true);
			return true;
		} else if (guiaRemision.getMotivotraslado().getMotivotrasladoid() == 0) {
			presentaMensaje(FacesMessage.SEVERITY_ERROR,
					"INGRESE UN MOTIVO DE TRANSLADO", "error", true);
			return true;
		} else if (listDetalleGuiaRemision.isEmpty()) {
			presentaMensaje(FacesMessage.SEVERITY_ERROR,
					"INGRESE FACTURAS PARA LA GUIA DE REMISION", "error", true);
			return true;
		}
		return false;
	}

	public void quitarDetalleGuiaRemision(List<Egreso> listaAuxFactura,
			List<Egreso> listaFacturasGuiaRemision,
			List<Egreso> listaQuitarFacturasGuiaRemision,
			List<Detalleguiaremision> listDetalleGuiaRemision, Persona cliente) {
		if (listaFacturasGuiaRemision.isEmpty())
			presentaMensaje(FacesMessage.SEVERITY_ERROR,
					"NO HAY FACTURAS PARA LA GUIA DE REMISION",
					"errorQuitarListaFactura", true);
		else {
			if (listaQuitarFacturasGuiaRemision.isEmpty())
				presentaMensaje(FacesMessage.SEVERITY_ERROR,
						"DEBE ESCOJER UNA FACTURA", "errorQuitarListaFactura",
						true);
			else {
				for (Egreso e : listaQuitarFacturasGuiaRemision)
					listaFacturasGuiaRemision.remove(e);

				listaAuxFactura.clear();
				listaAuxFactura.addAll(listaFacturasGuiaRemision);

				listDetalleGuiaRemision = new ArrayList<Detalleguiaremision>();
				cargarDetalleGuiaRemision(cliente, listaFacturasGuiaRemision,
						listaAuxFactura, listDetalleGuiaRemision);
				presentaMensaje(FacesMessage.SEVERITY_INFO, "CORRECTO",
						"errorQuitarListaFactura", false);
			}
		}
	}

	public List<Guiaremision> obtener(String criterioBusquedaCliente,
			String criterioBusquedaCodigo) {
		List<Guiaremision> lista = null;
		criterioBusquedaCliente = criterioBusquedaCliente.toUpperCase();
		criterioBusquedaCodigo = criterioBusquedaCodigo.toUpperCase();

		if (criterioBusquedaCliente.compareToIgnoreCase("") == 0
				&& criterioBusquedaCodigo.compareToIgnoreCase("") == 0)
			presentaMensaje(FacesMessage.SEVERITY_ERROR,
					"INGRESE UN CRITERIO DE BUSQUEDA");
		else if (criterioBusquedaCliente.length() >= 1
				&& criterioBusquedaCliente.length() <= 4) {
			presentaMensaje(FacesMessage.SEVERITY_ERROR,
					"INGRESE MAS DE 4 CARACTERES PARA LA BÚSQUEDA POR CLIENTES");
		} else if (!criterioBusquedaCodigo.matches("[0-9]*")) {
			presentaMensaje(FacesMessage.SEVERITY_ERROR,
					"INGRESE SOLO NÚMEROS PARA LA BÚSQUEDA POR DOCUMENTOS");
		} else if (criterioBusquedaCodigo.compareToIgnoreCase("") != 0
				&& criterioBusquedaCodigo.charAt(0) == '0') {
			presentaMensaje(FacesMessage.SEVERITY_ERROR,
					"NO SE PERMITE CEROS AL INICIO PARA LA BÚSQUEDA POR DOCUMENTOS");
		} else {
			if (criterioBusquedaCliente.compareTo("") != 0
					&& criterioBusquedaCodigo.compareTo("") != 0)
				lista = guiaRemisionDao
						.obtenerPorHql(
								"select distinct gr from Guiaremision gr "
										+ "inner join fetch gr.detalleguiaremisions "
										+ "inner join gr.cliente c inner join c.persona p "
										+ "where ((p.cedula like ?1 or p.apellido like ?1 or p.nombre like ?1) "
										+ "and gr.codigodocumento like ?2) "
										+ "order by gr.fechainicio asc",
								new Object[] {
										"%" + criterioBusquedaCliente + "%",
										"%" + criterioBusquedaCodigo + "%" });
			else if (criterioBusquedaCliente.compareTo("") != 0)
				lista = guiaRemisionDao
						.obtenerPorHql(
								"select distinct gr from Guiaremision gr "
										+ "inner join fetch gr.detalleguiaremisions "
										+ "inner join gr.cliente c inner join c.persona p "
										+ "where ((p.cedula like ?1 or p.apellido like ?1 or p.nombre like ?1) "
										+ "order by gr.fechainicio asc",
								new Object[] { "%" + criterioBusquedaCliente
										+ "%" });
			else if (criterioBusquedaCodigo.compareTo("") != 0)
				lista = guiaRemisionDao
						.obtenerPorHql(
								"select distinct gr from Guiaremision gr "
										+ "inner join fetch gr.detalleguiaremisions "
										+ "inner join gr.cliente c inner join c.persona p "
										+ "where gr.codigodocumento like ?1 "
										+ "order by gr.fechainicio asc",
								new Object[] { "%" + criterioBusquedaCodigo
										+ "%" });
			if (lista.isEmpty())
				presentaMensaje(FacesMessage.SEVERITY_INFO,
						"NO SE ENCONTRARON COINCIDENCIAS");
		}
		return lista;
	}

	public Guiaremision obtenerPorGuiaRemisionId(Long guiaRemisionId) {
		return (Guiaremision) guiaRemisionDao.obtenerPorHql(
				"select distinct gr from Guiaremision gr "
						+ "inner join fetch gr.detalleguiaremisions "
						+ "where gr.guiaremisionid=?1",
				new Object[] { guiaRemisionId }).get(0);
	}

}